﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace XmlSplitter
{
    class Program
    {
        static int MaxCount;
        static List<string> Files { get; set; } = new List<string>();
        static string Dir { get; set; }
        static string XmlTag { get; set; }
        static string FinalFileName { get; set; }
        static bool Join { get; set; }

        static void Main(string[] args)
        {
            try
            {
                Init(args);
            }
            catch(Exception e)
            {
                Console.WriteLine("ERROR: " + e.Message);
                Help();
            }
        }

        private static void Init(string[] args)
        {
            
            if (!args.Any())
            {
                Help();
                return;
            }
            if (!ProcessArgs(args))
            {
                Help();
                return;
            }
            
            if (Join)
            {
                var j = new XmlJoin(XmlTag, Files, Dir, FinalFileName);
                j.Exec();
                return;
            }
            Parallel.ForEach(Files, f =>
            {
                var s = new XmlSplit(XmlTag); 
                var dir = (new FileInfo(f)).Directory.FullName;
                string ndir = Path.Combine(dir, Path.GetFileNameWithoutExtension(f));
                if (!string.IsNullOrEmpty(Dir)) ndir = Dir;
                s.Exec(f, ndir, MaxCount);
            });
        }

        private static bool ProcessArgs(string[] args)
        {
            int joinIndex = Array.IndexOf<string>(args, "-join") + 1;
            int dirIndex = Array.IndexOf<string>(args, "-dir") + 1;
            int tagIndex = Array.IndexOf<string>(args, "-tag") + 1;
            int maxIndex = Array.IndexOf<string>(args, "-max") + 1;

            var c2 = (dirIndex > tagIndex ? dirIndex : tagIndex);
            int fileIndex = c2 > maxIndex ? c2 : maxIndex;
            fileIndex = fileIndex > joinIndex ? fileIndex : joinIndex;
            fileIndex += 1;
            Join = false;

            // check higher that 0 because -1 + 1 == 0!
            if (joinIndex > 0)
            {
                FinalFileName = args[joinIndex];
                Join = true;
            }
            if (dirIndex > 0)
            {
                Dir = args[dirIndex];
                if (!Directory.Exists(Dir))
                {
                    if (Join)
                    {
                        throw new DirectoryNotFoundException($"Direcotry {Dir} does not exist!");
                    }
                    Directory.CreateDirectory(Dir);
                }
            }
            if (tagIndex > 0)
            {
                XmlTag = args[tagIndex];
            }
            else
            {
                throw new Exception("-tag parameter is REQUIRED!");
            }
            if (maxIndex > 0)
            {
                if(!int.TryParse(args[maxIndex], out MaxCount))
                {
                    throw new Exception($"{args[maxIndex]} is not valid integer!");
                }
            }
            else if (!Join)
            {
                throw new Exception("-max parameter is REQUIRED!");
            }

            for (int i = fileIndex; i < args.Length; i++)
            {
                if (!File.Exists(args[i])) throw new FileNotFoundException($"File {args[i]} not found!");
                Files.Add(args[i]);
            }

            if (!Files.Any())
            {
                if (!Join && Dir.Length > 0)
                {
                    throw new Exception("Any XML files to split!");
                }
            }

            return true;
        }

        private static void Help()
        {
            Console.WriteLine(@"
XML SPLITTER ARGUMENTS:
-------------------
-dir    Directory to save result files. When this parameter is not used, files will be saved in subdir of file path.
        If JOIN param USING then all xml files in this directory will be joined!
-max    Max count of items in each file [REQUIRED]
-tag    Xml tag to split off [REQUIRED]
-join   Filename to join XML files
-------------------

These three options have to be set before files. All next arguments are taken as filenames:
-max 100 -tag xy:tag c:\temp\file.xml d:\temp\xml-file.xml etc...

JOIN:
-join c:\temp\joinfiles.xml -tag xy:tag c:\temp\file1.xml c:\temp\file2.xml
OR:
-join c:\temp\joinfiles.xml -tag xy:tag -dir c:\temp\dirxml

");
        }
    }

    
}
